home *** CD-ROM | disk | FTP | other *** search
/ Greenhouse Effect Detection Expriment / NASA Greenhouse Effect Detection Expriment 1992 - Disc 2.iso / software / dos / cdf22pc / src / tools / qop.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-19  |  9.0 KB  |  378 lines

  1. /******************************************************************************
  2. *
  3. *  NSSDC/CDF                Parse qualifiers/options/parameters.
  4. *
  5. *  Version 1.3, 10-Feb-92, ST Systems (STX)
  6. *
  7. *  Modification history:
  8. *
  9. *   V1.0  24-Jun-91, J Love    Original version (for CDF V2.1).
  10. *   V1.1  28-Jun-91, J Love    TRUE/FALSE.
  11. *   V1.2  23-Sep-91, J Love    Modified for IBM-PC port (CDF).
  12. *   V1.3  10-Feb-92, J Love    Ignore case on UNIX/MS-DOS machines.  Added
  13. *                checking for redundant qualifiers.  Added
  14. *                wildcard character (*) option in qualifiers
  15. *                (eg. -cdf and -cdfname will both match -cdf*).
  16. *
  17. ******************************************************************************/
  18.  
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <ctype.h>
  22. #include <string.h>
  23.  
  24. #include "qop.h"
  25.  
  26. #define NUL        0
  27.  
  28. /******************************************************************************
  29. * Local function prototypes.
  30. ******************************************************************************/
  31.  
  32. #if defined(vms) | defined(__MSDOS__)
  33. int strncmpNOCASEwild (char *, char *, size_t);
  34. #endif
  35.  
  36. #if defined(unix)
  37. int strncmpNOCASEwild ();
  38. #endif
  39.  
  40. /******************************************************************************
  41. * Qop.
  42. ******************************************************************************/
  43.  
  44. QOP *Qop (argc, argv, validQuals, optRequired)
  45. int argc;
  46. char *argv[];
  47. char *validQuals[];
  48. int optRequired[];
  49. {
  50. QOP *qop;
  51. int Nparms = 0;
  52. int matchQual;
  53. int i, j;
  54. char *parms[QOP_MAX_PARMs];
  55. int qualEntered[QOP_MAX_QUALs];
  56. char *qualOpt[QOP_MAX_QUALs];
  57. int strCount = 0;
  58. char *strOffset;
  59.  
  60. #if defined(vms)
  61. int Nquals = 0;
  62. char *argvTEMP[QOP_MAX_ARGVs];
  63. char *quals[QOP_MAX_QUALs];
  64. char *opts[QOP_MAX_QUALs];
  65. enum modes { UNKNOWN, FIND_QUAL, FIND_QUAL_END, FIND_PARM_END, FIND_OPT,
  66.          FIND_OPT_END } mode;
  67. #endif
  68.  
  69. #if defined(vms)
  70. /*****************************************************************************
  71. * Determine parameters and qualifiers/options - VMS.
  72. *****************************************************************************/
  73.  
  74. for (i = 1; i < argc; i++) {
  75.    argvTEMP[i] = (char *) malloc (strlen(argv[i]) + 1);
  76.    if (argvTEMP[i] == NULL) return NULL;            /* CLEAN UP! */
  77.    strcpy (argvTEMP[i], argv[i]);
  78.  
  79.    mode = UNKNOWN;
  80.  
  81.    for (j = 0; argvTEMP[i][j] != NUL; j++)
  82.       switch (mode) {
  83.     case UNKNOWN:
  84.          if (argvTEMP[i][j] == '/')
  85.            mode = FIND_QUAL;
  86.          else {
  87.            Nparms++;
  88.            if (Nparms <= QOP_MAX_PARMs) {
  89.              parms[Nparms-1] = &argvTEMP[i][j];
  90.            }
  91.            else {
  92.          printf ("Too many parameters.\n");
  93.          return NULL;
  94.            }
  95.            mode = FIND_PARM_END;
  96.          }
  97.          break;
  98.     case FIND_QUAL:
  99.          Nquals++;
  100.          if (Nquals <= QOP_MAX_QUALs) {
  101.            quals[Nquals-1] = &argvTEMP[i][j];
  102.          }
  103.          else {
  104.            printf ("Too many qualifiers.\n");
  105.            return NULL;
  106.          }
  107.          mode = FIND_QUAL_END;
  108.          break;
  109.     case FIND_QUAL_END:
  110.          switch (argvTEMP[i][j]) {
  111.         case '/':
  112.              argvTEMP[i][j] = NUL;
  113.              opts[Nquals-1] = NULL;
  114.              mode = FIND_QUAL;
  115.              break;
  116.         case '=':
  117.              argvTEMP[i][j] = NUL;
  118.              mode = FIND_OPT;
  119.              break;
  120.          }
  121.          break;
  122.     case FIND_PARM_END:
  123.          if (argvTEMP[i][j] == '/')
  124.            if (argvTEMP[i][j+1] == '/')
  125.          memmove (&argvTEMP[i][j], &argvTEMP[i][j+1],
  126.               strlen(&argvTEMP[i][j+1]) + 1);
  127.            else {
  128.          argvTEMP[i][j] = NUL;
  129.          mode = FIND_QUAL;
  130.            }
  131.          break;
  132.     case FIND_OPT:
  133.          if (argvTEMP[i][j] == '/')
  134.            if (argvTEMP[i][j+1] == '/') {
  135.          opts[Nquals-1] = &argvTEMP[i][j+1];
  136.          j++;
  137.          mode = FIND_OPT_END;
  138.            }
  139.            else {
  140.          argvTEMP[i][j] = NUL;
  141.          opts[Nquals-1] = &argvTEMP[i][j];
  142.          mode = FIND_QUAL;
  143.            }
  144.          else {
  145.            opts[Nquals-1] = &argvTEMP[i][j];
  146.            mode = FIND_OPT_END;
  147.          }
  148.          break;
  149.     case FIND_OPT_END:
  150.          if (argvTEMP[i][j] == '/')
  151.            if (argvTEMP[i][j+1] == '/')
  152.          memmove (&argvTEMP[i][j], &argvTEMP[i][j+1],
  153.               strlen(&argvTEMP[i][j+1]) + 1);
  154.            else {
  155.          argvTEMP[i][j] = NUL;
  156.          mode = FIND_QUAL;
  157.            }
  158.          break;
  159.       }
  160.  
  161.    switch (mode) {
  162.       case UNKNOWN:
  163.       case FIND_QUAL:
  164.        break;
  165.       case FIND_QUAL_END:
  166.        /* already NUL-terminated */
  167.        opts[Nquals-1] = NULL;
  168.        break;
  169.       case FIND_PARM_END:
  170.        /* already NUL-terminated */
  171.        break;
  172.       case FIND_OPT:
  173.        opts[Nquals - 1] = &argvTEMP[i][j];        /* NUL-string */
  174.        break;
  175.       case FIND_OPT_END:
  176.        /* already NUL-terminated */
  177.        break;
  178.    }
  179. }
  180.  
  181. /*****************************************************************************
  182. * Determine which qualifiers/options were entered - VMS.
  183. *****************************************************************************/
  184.  
  185. for (i = 0; validQuals[i] != NULL; i++) {
  186.    if (i < QOP_MAX_QUALs) {
  187.      qualEntered[i] = FALSE;
  188.      qualOpt[i] = NULL;
  189.    }
  190.    else {
  191.      printf ("Too many valid qualifiers.\n");
  192.      return NULL;
  193.    }
  194. }
  195.  
  196. for (i = 0; i < Nquals; i++) {
  197.    matchQual = -1;
  198.    for (j = 0; validQuals[j] != NULL; j++)
  199.       if (strncmpNOCASEwild(quals[i], validQuals[j], strlen(quals[i])) == 0)
  200.     if (matchQual != -1) {
  201.       printf ("Ambiguous qualifier (/%s).\n", quals[i]);
  202.       return NULL;
  203.     }
  204.     else {
  205.       matchQual = j;
  206.     }
  207.    if (matchQual != -1)
  208.      if (optRequired[matchQual] && opts[i] == NULL) {
  209.        printf ("Option missing for qualifier /%s.\n", validQuals[matchQual]);
  210.        return NULL;
  211.      }
  212.      else {
  213.        if (qualEntered[matchQual]) {
  214.      printf ("Redundant qualifier (/%s).\n", validQuals[matchQual]);
  215.      return NULL;
  216.        }
  217.        else {
  218.      qualEntered[matchQual] = TRUE;
  219.      qualOpt[matchQual] = opts[i];
  220.        }
  221.      }
  222.    else {
  223.      printf ("Unknown qualifier (/%s).\n", quals[i]);
  224.      return NULL;
  225.    }
  226. }
  227. #endif
  228.  
  229. #if defined(unix) | defined(__MSDOS__)
  230. /*****************************************************************************
  231. * Determine which qualifiers/options were entered - UNIX/MS-DOS.
  232. *****************************************************************************/
  233.  
  234. for (i = 0; validQuals[i] != NULL; i++) {
  235.    if (i < QOP_MAX_QUALs) {
  236.      qualEntered[i] = FALSE;
  237.      qualOpt[i] = NULL;
  238.    }
  239.    else {
  240.      printf ("Too many valid qualifiers.\n");
  241.      return NULL;
  242.    }
  243. }
  244.  
  245. for (i = 1; i < argc; i++)
  246.    if (argv[i][0] == '-') {
  247.      matchQual = -1;
  248.  
  249.      for (j = 0; validQuals[j] != NULL; j++)
  250.     if (strncmpNOCASEwild(&argv[i][1],
  251.                   validQuals[j], strlen(&argv[i][1])) == 0)
  252.       if (matchQual != -1) {
  253.         printf ("Ambiguous qualifier (-%s).\n", &argv[i][1]);
  254.         return NULL;
  255.       }
  256.       else
  257.         matchQual = j;
  258.  
  259.      if (matchQual != -1) {
  260.        if (qualEntered[matchQual]) {
  261.      printf ("Redundant qualifier (-%s).\n", validQuals[matchQual]);
  262.      return NULL;
  263.        }
  264.        else {
  265.      qualEntered[matchQual] = TRUE;
  266.        }
  267.  
  268.        if (optRequired[matchQual])
  269.      if (i+1 < argc) {
  270.        qualOpt[matchQual] = argv[i+1];
  271.        i++;
  272.      }
  273.      else {
  274.        printf ("Option missing for qualifier -%s.\n",
  275.            validQuals[matchQual]);
  276.        return NULL;
  277.      }
  278.      }
  279.      else {
  280.        printf ("Unknown qualifier (-%s).\n", &argv[i][1]);
  281.        return NULL;
  282.      }
  283.    }
  284.    else {
  285.      Nparms++;
  286.      if (Nparms <= QOP_MAX_PARMs) {
  287.        parms[Nparms-1] = argv[i];
  288.      }
  289.      else {
  290.        printf ("Too many parameters.\n");
  291.        return NULL;
  292.      }
  293.    }
  294. #endif
  295.  
  296. /******************************************************************************
  297. * Build QOP structure.
  298. ******************************************************************************/
  299.  
  300. for (i = 0; i < Nparms; i++) strCount += strlen(parms[i]) + 1;
  301.  
  302. for (i = 0; validQuals[i] != NULL; i++)
  303.    if (qualEntered[i])
  304.      if (qualOpt[i] != NULL) strCount += strlen(qualOpt[i]) + 1;
  305.  
  306. qop = (QOP *) malloc (sizeof(QOP) + strCount);
  307. if (qop == NULL) return NULL;
  308.  
  309. strOffset = (char *) qop + sizeof(QOP);
  310.  
  311. qop->Nparms = Nparms;
  312.  
  313. for (i = 0; i < Nparms; i++) {
  314.    qop->parms[i] = strOffset;
  315.    strOffset += strlen(parms[i]) + 1;
  316.    strcpy (qop->parms[i], parms[i]);
  317. }
  318.  
  319. for (i = 0; validQuals[i] != NULL; i++) {
  320.    qop->qualEntered[i] = qualEntered[i];
  321.    if (qualEntered[i])
  322.      if (qualOpt[i] != NULL) {
  323.        qop->qualOpt[i] = strOffset;
  324.        strOffset += strlen(qualOpt[i]) + 1;
  325.        strcpy (qop->qualOpt[i], qualOpt[i]);
  326.      }
  327.      else
  328.        qop->qualOpt[i] = NULL;
  329. }
  330.  
  331. /******************************************************************************
  332. * Free memory used.
  333. ******************************************************************************/
  334.  
  335. #if defined(vms)
  336. for (i = 1; i < argc; i++) free (argvTEMP[i]);
  337. #endif
  338.  
  339. /*****************************************************************************/
  340.  
  341. return qop;
  342. }
  343.  
  344. /******************************************************************************
  345. * strncmpNOCASEwild.
  346. ******************************************************************************/
  347.  
  348. static int strncmpNOCASEwild (s1, s2, len)
  349. char *s1;
  350. char *s2;
  351. size_t len;
  352. {
  353. int i;
  354.  
  355. for (i = 0; i < len; i++)
  356.    switch (s1[i]) {
  357.      case NUL:
  358.        if (s2[i] == '*')
  359.      return 0;
  360.        else
  361.      return -s2[i];
  362.      case '*':
  363.        return 0;
  364.      default:
  365.        switch (s2[i]) {
  366.      case NUL:
  367.        return s1[i];
  368.      case '*':
  369.        return 0;
  370.      default:
  371.        if ((islower(s1[i]) ? toupper(s1[i]) : s1[i]) !=
  372.            (islower(s2[i]) ? toupper(s2[i]) : s2[i])) return s1[i] - s2[i];
  373.        }
  374.    }
  375.  
  376. return 0;
  377. }
  378.